package com.dg11185.nearshop.baidumap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.security.auth.PrivateCredentialPermission;

import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.android.nearshop.R;
import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapStatusChangeListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.dg11185.libs.network.NetClient;
import com.dg11185.nearshop.activity.shop.ShopDetailActivity;
import com.dg11185.nearshop.app.Constants;
import com.dg11185.nearshop.app.ConvertUnit;
import com.dg11185.nearshop.app.DataCache;
import com.dg11185.nearshop.app.ViewUtils;
import com.dg11185.nearshop.baidumap.mai.ShakeListener;
import com.dg11185.nearshop.baidumap.mai.ShakeListener.OnShakeListener;
import com.dg11185.nearshop.net.NetCacheClient;
import com.dg11185.nearshop.net.entity.MerchantItem;
import com.dg11185.nearshop.net.request.GetMerchantListRequest;
import com.dg11185.nearshop.net.response.GetMerchantListResponse;
import com.dg11185.nearshop.net.response.NetStatus;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.view.ViewHelper;

/**
 * 地图商家列表界面
 * 
 * @author：Daibo
 * @time：2014-7-18 下午3:17:20
 */
public class NearshopActivity extends BaseMapActivity implements OnClickListener {

    private final int SHOP = 0;

    private final int DISTRICT = 1;

    private int mapStatus = DISTRICT;

    private final float SHOP_LEVEL = 14.0f;

    private final float DISTRICT_LEVEL = 12.5f;

    public float CURRENT_ZOOM_LEVEL = DISTRICT_LEVEL;

    // 设置东莞市的经纬度范围，超过该经纬度不再加载商家。
    private final static double FROM_LAT = 22.63415;

    private final static double TO_LAT = 23.293405;

    private final static double FROM_LONG = 113.506159;

    private final static double TO_LONG = 114.284595;

    private LatLng CURRENT_POI = MapConstant.getDefaultPoint();

    /** 第一次点击摇摇按钮，弹出文字提示信息 */
    private boolean isFristClick = true;

    private int curPageNo = 1, pageSize = 20, total = 0;

    /** 当前被点击的Item，用户选择查看详情时传递数据 */
    private int currentSelectedIndex = 0;

    private LinearLayout moveLayout = null;

    private LinearLayout dataLayout = null;

    private TextView title, address;

    private HashMap<String, BitmapDescriptor> iconMap = new HashMap<String, BitmapDescriptor>();

    /** 用于获取接口商家数据 */
    private List<MerchantItem> shopOverlayDatas = null;

    private GetMerchantListRequest request = null;

    /** 摇一摇功能 */
    private ShakeListener mShakeListener = null;

    /** 选择栏 */
    private ListView listView;

    private TextView txtIndustry;

    private Dialog loadingDialog = null;

    private Handler mHandler = new Handler();

    private ImageView mShakeOrRefreshBtn;

    private final static long SHAKE_INTERVAL = 5000;// 摇摇按钮动画启动的时间间隔

    private Animation shakeAnim;// 晃动动画

    private NearshopHelper helper = null;

    // 新线程，用于控制摇摇按钮的动画效果
    // 每隔5秒，图标晃动一次
    private Runnable mShakeRun = new Runnable() {
        @Override
        public void run() {
            mHandler.postDelayed(mShakeRun, SHAKE_INTERVAL);
            if (mShakeOrRefreshBtn != null && shakeAnim != null) {
                mShakeOrRefreshBtn.startAnimation(shakeAnim);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        shakeAnim = AnimationUtils.loadAnimation(this, R.anim.shake_anim);
        mHandler.postDelayed(mShakeRun, SHAKE_INTERVAL);
        listView = (ListView) this.findViewById(R.id.nearshop_list);
        txtIndustry = (TextView) this.findViewById(R.id.nearshop_industry);
        moveLayout = (LinearLayout) this.findViewById(R.id.nearshop_move_layout);
        dataLayout = (LinearLayout) this.findViewById(R.id.nearshop_data_layout);
        title = (TextView) this.findViewById(R.id.nearshop_data_title);
        address = (TextView) this.findViewById(R.id.nearshop_detail_address);
        loadingDialog = ViewUtils.createLoadingDialog(this);
        findViewById(R.id.nearshop_txt_layout).setOnClickListener(this);
        findViewById(R.id.nearshop_back).setOnClickListener(this);
        findViewById(R.id.nearshop_data_detail).setOnClickListener(this);
        findViewById(R.id.nearshop_data_route).setOnClickListener(this);
        mShakeOrRefreshBtn = (ImageView) findViewById(R.id.nearshop_refresh);
        mShakeOrRefreshBtn.setOnClickListener(this);
        shopOverlayDatas = new ArrayList<MerchantItem>();

        mShakeListener = new ShakeListener(this);
        mShakeListener.setOnShakeListener(new MyShakeListener());

        initMapLocation();
        helper = new NearshopHelper(this, mBaiduMap);
        helper.initShopNumOverlay(Constants.AREA_NUM, "");
        initListView();
        initMapListener();
    }

    @Override
    public void setContentView() {
        setContentView(R.layout.map_nearshop);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mShakeListener.start();
    }

    @Override
    protected void onPause() {
        mShakeListener.stop();
        NetClient.httpCancel(this, true);
        super.onPause();
    }

    /***
     * 初始化定位
     */
    private void initMapLocation() {
        addLocOverlay();
        Set<Entry<String, Integer>> set = MapConstant.getIndustryIconMap().entrySet();
        Iterator<Entry<String, Integer>> it = set.iterator();
        while (it.hasNext()) {
            Entry<String, Integer> entry = it.next();
            iconMap.put(entry.getKey(), BitmapDescriptorFactory.fromResource(entry.getValue()));
        }

        request = new GetMerchantListRequest(Constants.AREA_NUM);
        request.add(request.PAGE_SIZE, pageSize + "").add(request.PAGE_NUM, curPageNo + "")
                .add(request.RADIUS, Constants.DEFAULT_RADIUS + "").add(request.ORDER_NAME, request.RADIUS)
                .add(request.ORDER_TYPE, "0");
    }

    @Override
    /**定位回调*/
    public void onReceiveLocation(BDLocation location) {

        // map view 销毁后不在处理新接收的位置
        if (location == null || mMapView == null) {
            return;
        }
        // 显示定位图层
        MyLocationData locData = new MyLocationData.Builder().accuracy(location.getRadius())
                .direction(location.getDirection()).latitude(location.getLatitude()).longitude(location.getLongitude())
                .build();
        mBaiduMap.setMyLocationData(locData);
        LatLng myPoi = new LatLng(location.getLatitude(), location.getLongitude());

        float curLevel = 0.0f;
        if (mapStatus == DISTRICT) {
            curLevel = DISTRICT_LEVEL;
        } else {
            if (txtIndustry.getText().toString().equals("全部分类")) {
                curLevel = SHOP_LEVEL + 2;
            } else {
                curLevel = SHOP_LEVEL + 1;
            }
        }
        MapStatusUpdate update = MapStatusUpdateFactory.newLatLngZoom(myPoi, curLevel);
        mBaiduMap.animateMapStatus(update);
    }

    private class MyShakeListener implements OnShakeListener {

        @Override
        public void onShake() {
            if (request != null) {
                if (mapStatus == SHOP) {
                    initShopListData();
                }
            }
        }

    }

    /**
     * 初始化界面需要点的数据
     */
    public void initShopListData() {
        double curLat = Double.parseDouble(request.getParams().get(request.LATITUDE));
        double curLong = Double.parseDouble(request.getParams().get(request.LONGITUDE));
        if (curLat > TO_LAT || curLat < FROM_LAT || curLong > TO_LONG || curLong < FROM_LONG) {
            return;
        }
        loadingDialog.show();
        dismissDataView();
        if (request != null) {
            request.getParams().remove("chshSign");
        }
        request.add(request.PAGE_NUM, curPageNo + "").encryption();
        request.setActionListener(new GetMerchantListRequest.ActionListener<GetMerchantListResponse>() {
            @Override
            public void onSuccess(GetMerchantListResponse result) {
                loadingDialog.dismiss();
                if (result.status == NetStatus.SUCCESS) {
                    total = Integer.parseInt(result.total);
                    if (result.merchants.size() > 0) {
                        if (curPageNo * pageSize > total) {
                            curPageNo = 1;
                        } else {
                            curPageNo++;
                        }
                        shopOverlayDatas.clear();
                        shopOverlayDatas.addAll(result.merchants);
                        currentSelectedIndex = 0;
                        initOverlay();
                    }
                } else {
                    onFailure(-1);
                }
            }

            @Override
            public void onFailure(int resultCode) {
                loadingDialog.dismiss();
                if (resultCode == NetClient.NET_DISCONNECT_CODE) {
                    ViewUtils.showToast(NearshopActivity.this, "当前无网络连接...");
                } else {
                    ViewUtils.showToast(NearshopActivity.this, "获取数据失败...");
                }
            }
        });
        NetCacheClient.httpGet(request);
    }

    private void initOverlay() {
        mBaiduMap.clear();
        for (int index = 0; index < shopOverlayDatas.size(); index++) {

            double lat = Double.parseDouble(shopOverlayDatas.get(index).latitude);
            double log = Double.parseDouble(shopOverlayDatas.get(index).longitude);
            LatLng poi = new LatLng(lat, log);
            String industryId = shopOverlayDatas.get(index).industryId;
            if (industryId == null) {
                industryId = "106";
            } else if (industryId.length() < 3) {
                industryId = "106";
            } else {
                industryId = industryId.substring(0, 3);
            }
            OverlayOptions options = new MarkerOptions().zIndex(index).position(poi).icon(iconMap.get(industryId));
            mBaiduMap.addOverlay(options);
        }
    }

    protected void onDestroy() {
        helper.releseDbHelper();
        Set<Entry<String, BitmapDescriptor>> set = iconMap.entrySet();
        Iterator<Entry<String, BitmapDescriptor>> it = set.iterator();
        while (it.hasNext()) {
            Entry<String, BitmapDescriptor> entry = it.next();
            entry.getValue().recycle();
        }
        super.onDestroy();
    };

    private void initListView() {
        ArrayList<Map<String, Object>> listData = new ArrayList<Map<String, Object>>();
        for (int a = 0; a < MapConstant.industrys.length; a++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("CONTENT", MapConstant.industrys[a]);
            listData.add(map);
        }
        SimpleAdapter adapter = new SimpleAdapter(this, listData, R.layout.map_nearshop_item,
                new String[] { "CONTENT" }, new int[] { R.id.nearshop_shop_item_txt });
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                String industryName = MapConstant.industrys[position];
                String industryId = MapConstant.getIndustryMap().get(industryName);
                helper.initShopNumOverlay(Constants.AREA_NUM, industryId);
                mapStatus = DISTRICT;

                MapStatusUpdate update = MapStatusUpdateFactory.zoomTo(DISTRICT_LEVEL);
                mBaiduMap.animateMapStatus(update);
                txtIndustry.setCompoundDrawablesWithIntrinsicBounds(null, null,
                        getResources().getDrawable(R.drawable.ic_white_arrow_small_down), null);
                ObjectAnimator oa = ObjectAnimator.ofFloat(listView, "scaleY", 1, 0);
                oa.addListener(new ListAnimListener());
                oa.setDuration(200).start();
                if (request != null) {
                    String industry = MapConstant.industrys[position];
                    txtIndustry.setText(industry);
                    if ("全部分类".equals(industry)) {
                        request.getParams().remove("industryId");
                    } else {
                        request.add("industryId", MapConstant.getIndustryMap().get(industry));
                    }
                }
            }

        });
    }

    private class ListAnimListener extends AnimatorListenerAdapter {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            listView.setVisibility(View.GONE);
        }
    }

    /** 地图上所有监听事件 */
    private void initMapListener() {
        mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {

            @Override
            public boolean onMarkerClick(final Marker marker) {
                if (mapStatus == SHOP) {
                    currentSelectedIndex = marker.getZIndex();
                    title.setText(shopOverlayDatas.get(currentSelectedIndex).merchantName);
                    address.setText(shopOverlayDatas.get(currentSelectedIndex).address);
                    showDataView();
                } else if (mapStatus == DISTRICT) {
                    mBaiduMap.clear();
                    int index = marker.getZIndex();
                    LatLng latLng = new LatLng(helper.getAreas().get(index).latitude,
                            helper.getAreas().get(index).longitude);
                    request.add(request.LATITUDE, latLng.latitude + "");
                    request.add(request.LONGITUDE, latLng.longitude + "");
                    CURRENT_POI = latLng;

                    float curLevel = SHOP_LEVEL;
                    int merchat_count = helper.getMerchantCount(helper.getAreas().get(index).areaNum);
                    if (merchat_count > 20 || merchat_count < 5) {
                        curLevel = SHOP_LEVEL + 2;
                    } else if (merchat_count > 10) {
                        curLevel = SHOP_LEVEL + 1;
                    } else {
                    }
                    MapStatusUpdate update = MapStatusUpdateFactory.newLatLngZoom(latLng, curLevel);
                    mBaiduMap.animateMapStatus(update);
                }
                return false;
            }
        });

        mBaiduMap.setOnMapClickListener(new OnMapClickListener() {

            @Override
            public boolean onMapPoiClick(MapPoi arg0) {
                return false;
            }

            @Override
            public void onMapClick(LatLng arg0) {
                dismissDataView();
            }
        });
        mBaiduMap.setOnMapStatusChangeListener(new OnMapStatusChangeListener() {

            @Override
            public void onMapStatusChangeStart(MapStatus arg0) {
                dismissDataView();
            }

            @Override
            public void onMapStatusChangeFinish(MapStatus arg0) {

                // TODO
                float zoomLevel = mBaiduMap.getMapStatus().zoom;
                LatLng latLng = mBaiduMap.getMapStatus().target;
                System.out.println("cur: " + zoomLevel + "     pre: " + CURRENT_ZOOM_LEVEL);
                if (zoomLevel >= SHOP_LEVEL && CURRENT_ZOOM_LEVEL < SHOP_LEVEL) {
                    mapStatus = SHOP;
                    onMapTranslate();
                } else if (zoomLevel >= SHOP_LEVEL && CURRENT_ZOOM_LEVEL >= SHOP_LEVEL) {
                    System.out.println(ConvertUnit.getDistance1(latLng.latitude, latLng.longitude,
                            CURRENT_POI.latitude, CURRENT_POI.longitude));
                    if (ConvertUnit.getDistance1(latLng.latitude, latLng.longitude, CURRENT_POI.latitude,
                            CURRENT_POI.longitude) > 1000) {
                        mapStatus = SHOP;
                        onMapTranslate();
                    }
                } else if (zoomLevel <= DISTRICT_LEVEL && CURRENT_ZOOM_LEVEL > DISTRICT_LEVEL) {
                    mapStatus = DISTRICT;
                    helper.displayOverlay();
                } else {

                }
                CURRENT_ZOOM_LEVEL = zoomLevel;
            }

            @Override
            public void onMapStatusChange(MapStatus arg0) {
            }
        });
    }

    // 地图显示在商家状态下，如果地图移动、缩放导致中心点变化
    private void onMapTranslate() {
        LatLng latLng = mBaiduMap.getMapStatus().target;
        CURRENT_POI = latLng;
        curPageNo = 1;
        request.add(request.LATITUDE, latLng.latitude + "");
        request.add(request.LONGITUDE, latLng.longitude + "");
        initShopListData();
    }

    private void dismissDataView() {
        if (dataLayout.getVisibility() == View.VISIBLE) {
            ObjectAnimator oa = ObjectAnimator.ofFloat(moveLayout, "translationY", 0, dataLayout.getHeight());

            oa.setDuration(200);
            oa.start();
            oa.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    dataLayout.setVisibility(View.INVISIBLE);
                }
            });
        }
    }

    private void showDataView() {
        if (dataLayout.getVisibility() != View.VISIBLE) {
            dataLayout.setVisibility(View.VISIBLE);
            ObjectAnimator.ofFloat(moveLayout, "translationY", dataLayout.getHeight(), 0).setDuration(200).start();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.nearshop_txt_layout:
            ViewHelper.setPivotX(listView, 0);
            ViewHelper.setPivotY(listView, 0);
            if (View.GONE == listView.getVisibility()) {
                ObjectAnimator.ofFloat(listView, "scaleY", 0, 1).setDuration(200).start();
                txtIndustry.setCompoundDrawablesWithIntrinsicBounds(null, null,
                        getResources().getDrawable(R.drawable.ic_white_arrow_small_up), null);
                listView.setVisibility(View.VISIBLE);
            } else {
                txtIndustry.setCompoundDrawablesWithIntrinsicBounds(null, null,
                        getResources().getDrawable(R.drawable.ic_white_arrow_small_down), null);
                ObjectAnimator oa = ObjectAnimator.ofFloat(listView, "scaleY", 1, 0);
                oa.addListener(new ListAnimListener());
                oa.setDuration(200).start();
            }
            break;
        case R.id.nearshop_back:
            this.finish();
            break;
        case R.id.nearshop_data_detail:
            Intent intent = new Intent(this, ShopDetailActivity.class);
            intent.putExtra("merchant_id", shopOverlayDatas.get(currentSelectedIndex).merchantId);
            startActivity(intent);
            break;
        case R.id.nearshop_data_route:
            MerchantItem shopData = shopOverlayDatas.get(currentSelectedIndex);
            DataCache.setValue(MapConstant.dataShopInfoForMap, new EntityShopData(shopData));
            startActivity(new Intent(this, ChoiceRouteActivity.class));
            break;
        case R.id.nearshop_refresh:
            if (isFristClick) {
                com.wlper.lib.uitls.ViewUtils.showToast(this, "摇一摇也能刷新哦~");
                isFristClick = false;
            }
            if (request == null)
                break;
            initShopListData();
            break;
        default:
            break;
        }
    }
}
